package com.aw.baselib.util

import android.text.TextUtils
import com.google.gson.Gson
import com.google.gson.JsonNull
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.lang.reflect.Type

/**
 * Created by hzw
 */
class AwJsonUtil private constructor() {
    var gson: Gson

    init {
        gson = Gson()
    }

    /**
     * 将对象转为JSON串，此方法能够满足大部分需求
     *
     * @param src :将要被转化的对象
     * @return :转化后的JSON串
     */
    fun toJson(src: Any?): String {
        return if (src == null) {
            gson.toJson(JsonNull.INSTANCE)
        } else gson.toJson(src)
    }

    /**
     * 用来将JSON串转为对象，但此方法不可用来转带泛型的集合
     *
     * @param json     json串
     * @param classOfT 需要转换的类class
     * @return
     */
    fun <T> fromJson(json: String?, classOfT: Class<T>?): Any {
        return gson.fromJson(json, classOfT as Type?)
    }

    /**
     * 用来将 JSON串 转为对象，此方法可用来转带泛型的集合，
     * 如：Type 为 new TypeToken<List></List><T>>(){}.getType()，
     * 其它类也可以用此方法调用，就是将List<T>替换为你想要转成的类
     *
     * @param json    json串
     * @param typeOfT 需要转换的类class
     * @return
    </T></T> */
    fun fromJson(json: String?, typeOfT: Type?): Any {
        return gson.fromJson(json, typeOfT)
    }

    /**
     * 用来将 JSON串 转为对象，此方法可用来转带泛型的集合
     * 如：Type为 new TypeToken<List></List><T>>(){}.getType()其它类也可以用此方法调用，
     * 就是将List<T>替换为你想要转成的类
     *
     * @param json
     * @param typeOfT
     * @return
    </T></T> */
    fun fromJsonArray(json: String?, typeOfT: Type?): List<Any> {
        return gson.fromJson(json, typeOfT)
    }

    companion object {
        private var mInstance: AwJsonUtil? = null
        val instance: AwJsonUtil?
            get() {
                if (mInstance == null) {
                    synchronized(AwJsonUtil::class.java) {
                        if (mInstance == null) {
                            mInstance = AwJsonUtil()
                        }
                    }
                }
                return mInstance
            }

        /**
         * 将 json字符串 的key->value转为 HashMap
         *
         * @param jsonStr json字符串
         * @return
         */
        fun jsonToMap(jsonStr: String?): HashMap<String, String> {
            val map = HashMap<String, String>()
            if (TextUtils.isEmpty(jsonStr)) {
                return HashMap()
            }
            try {
                // 将 json 转为 JSONObject
                val obj = JSONObject(jsonStr)

                // 获取所以key值
                val strKeys: Iterator<*> = obj.keys()
                //遍历JSONObject
                while (strKeys.hasNext()) {
                    val key = strKeys.next().toString()
                    var value = obj.getString(key)
                    if (value == null || value == "null") {
                        value = ""
                    }
                    map[key] = value
                }
                return map
            } catch (e: JSONException) {
                e.printStackTrace()
            }
            return HashMap()
        }

        /**
         * 将 json字符串 的key->value转为 List<HashMap>
         *
         * @param jsonStr json字符串
         * @return
        </HashMap> */
        fun jsonToList(jsonStr: String?): ArrayList<HashMap<String, String>> {
            val arrayList = ArrayList<HashMap<String, String>>()
            if (TextUtils.isEmpty(jsonStr)) {
                return arrayList
            }
            try {
                // 将 json 转为 jsonArray
                val jsonArray = JSONArray(jsonStr)

                // 开始遍历
                for (i in 0 until jsonArray.length()) {
                    val obj = jsonArray.getJSONObject(i)
                    val map = HashMap<String, String>()
                    val strKeys: Iterator<*> = obj.keys()
                    while (strKeys.hasNext()) {
                        val key = strKeys.next().toString()
                        var value = obj.getString(key)
                        if (value == null || value == "null") {
                            value = ""
                        }
                        map[key] = value
                    }
                    arrayList.add(map)
                }
                return arrayList
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return ArrayList()
        }
    }
}